アニメーションのチュートリアル
このチュートリアルでは、Flutter で明示的なアニメーションを構築する方法を説明します。 いくつかの重要な概念、クラスを紹介した後、 およびアニメーション ライブラリのメソッドについて、5 つの手順を説明します。 アニメーションの例。例は相互に構築されており、 アニメーション ライブラリのさまざまな側面を紹介します。
Flutter SDK には、組み込みの明示的なアニメーションも提供されます。
そのようなFadeTransition
、SizeTransition
、
とSlideTransition
。これらの単純なアニメーションは、
開始点と終了点を設定することでトリガーされます。
実装が簡単です
ここで説明するカスタムの明示的なアニメーションよりも優れています。
アニメーションの基本的な概念とクラス
Flutter のアニメーション システムは型指定に基づいています。Animation
オブジェクト。ウィジェットは次のいずれかを組み込むことができます
ビルド関数内のこれらのアニメーションは、次のように直接実行されます。
現在の値を読み取り、その状態を聞く
変更することも、アニメーションをベースとして使用することもできます。
より精巧なアニメーションが引き継がれます
他のウィジェット。
<ダブル>
アニメーションFlutter では、Animation
オブジェクトは何について何も知りません
が画面上にあります。アンAnimation
は抽象クラスです。
現在の値とその状態 (完了または拒否) を理解します。
最も一般的に使用されるアニメーション タイプの 1 つは次のとおりです。Animation<double>
。
アンAnimation
オブジェクトが順次生成する
一定期間にわたる 2 つの値の間の補間された数値。
の出力Animation
オブジェクトは線形である可能性がありますが、
曲線、ステップ関数、またはその他のマッピングを考案できます。
方法に応じて、Animation
オブジェクトが制御され、
逆走したり、方向を変えたりする可能性もあります。
真ん中。
アニメーションでは、double 以外のタイプも補間できます。Animation<Color>
またAnimation<Size>
。
アン98bf9592-0d73-4a18-8304-fc8e6eaaaacaeオブジェクトには状態があります。現在の値は
でいつでも利用可能.value
メンバー。
アンAnimation
オブジェクトはレンダリングについて何も知らない、またはbuild()
機能。
曲線アニメーション
あCurvedAnimation
アニメーションの進行状況を定義します
非線形曲線として。
animation = CurvedAnimation(parent: controller, curve: Curves.easeIn);
CurvedAnimation
とAnimationController
(次のセクションで説明します)
どちらもタイプですAnimation<double>
, したがって、これらを交換して渡すことができます。
のCurvedAnimation
変更しているオブジェクトをラップします。
サブクラス化しないAnimationController
曲線を実装します。
アニメーションコントローラー
AnimationController
特別ですAnimation
ハードウェアが壊れるたびに新しい値を生成するオブジェクト
新しいフレームの準備ができています。デフォルトでは、
のAnimationController
数値を線形に生成します
指定された期間中に 0.0 から 1.0 まで変化します。
たとえば、このコードはAnimation
物体、
しかし、実行は開始されません:
controller =
AnimationController(duration: const Duration(seconds: 2), vsync: this);
AnimationController
から派生Animation<double>
, 使えるので
どこにでもAnimation
オブジェクトが必要です。しかしAnimationController
にはアニメーションを制御する追加のメソッドがあります。たとえば、あなたは始めます
を使ったアニメーション.forward()
方法。数値の生成は、
画面の更新に関連付けられているため、通常は 1 回につき 60 個の数値が生成されます。
2番。各数値が生成された後、それぞれAnimation
オブジェクトが呼び出す
添付Listener
オブジェクト。それぞれのカスタム表示リストを作成するには
子供、見てくださいRepaintBoundary
。
を作成するときは、AnimationController
、あなたはそれを渡しますvsync
口論。
の存在vsync
オフスクリーンアニメーションが消費されるのを防ぎます
不要なリソース。
を追加することで、ステートフル オブジェクトを vsync として使用できます。SingleTickerProviderStateMixin
クラス定義に。
この例は次のとおりです。アニメート1GitHub 上で。
トゥイーン
デフォルトでは、AnimationController
オブジェクトの範囲は 0.0 ~ 1.0 です。
別の範囲または別のデータ型が必要な場合は、Tween
に補間するアニメーションを設定するには
範囲またはデータ型が異なります。たとえば、
続くTween
-200.0 から 0.0 まで変化します。
tween = Tween<double>(begin: -200, end: 0);
あTween
のみを受け取るステートレスオブジェクトですbegin
とend
。
の唯一の仕事Tween
からマッピングを定義することです。
入力レンジから出力レンジまで。入力レンジは一般的に
0.0 ~ 1.0 ですが、これは必須ではありません。
あTween
から継承しますAnimatable<T>
、からではありませんAnimation<T>
。
アンAnimatable
、 好きAnimation
、double を出力する必要はありません。
例えば、ColorTween
2 つの色の間の進行を指定します。
colorTween = ColorTween(begin: Colors.transparent, end: Colors.black54);
あTween
オブジェクトは状態を保存しません。代わりに、evaluate(Animation<double> animation)
を使用するメソッドtransform
アニメーションの現在値をマップする関数
(0.0 ~ 1.0)、実際のアニメーション値に合わせます。
現在の値Animation
オブジェクトは次の場所にあります。.value
方法。評価関数はハウスキーピングも実行します。
たとえば、次のときに begin と end が返されるようにするなどです。
アニメーション値はそれぞれ 0.0 と 1.0 です。
トゥイーンアニメイト
を使用するにはTween
オブジェクト、呼び出しanimate()
でTween
、
コントローラーオブジェクトを渡します。例えば、
次のコードは、
500 ミリ秒にわたる 0 ~ 255 の整数値。
AnimationController controller = AnimationController(
duration: const Duration(milliseconds: 500), vsync: this);
Animation<int> alpha = IntTween(begin: 0, end: 255).animate(controller);
次の例は、コントローラー、カーブ、およびTween
:
AnimationController controller = AnimationController(
duration: const Duration(milliseconds: 500), vsync: this);
final Animation<double> curve =
CurvedAnimation(parent: controller, curve: Curves.easeOut);
Animation<int> alpha = IntTween(begin: 0, end: 255).animate(curve);
アニメーション通知
アンAnimation
オブジェクトは持つことができますListener
砂StatusListener
さん、
で定義されたaddListener()
とaddStatusListener()
。
あListener
アニメーションの値が変更されるたびに呼び出されます。
最も一般的な行動は、Listener
電話することですsetState()
再構築を引き起こすため。あStatusListener
アニメーションの開始時に呼び出されます。
で定義されるように、終了、前進、または後退します。AnimationStatus
。
次のセクションでは例を示します。addListener()
方法、
とアニメーションの進行状況を監視するを示しています
の例addStatusListener()
。
アニメーションの例
このセクションでは、5 つのアニメーションの例を説明します。 各セクションには、その例のソース コードへのリンクが含まれています。
アニメーションのレンダリング
ここまでは、時間の経過とともに一連の数値を生成する方法を学習しました。
画面には何もレンダリングされていません。を使用してレンダリングするにはAnimation
オブジェクトを保存するAnimation
としてのオブジェクト
ウィジェットのメンバーを作成し、その値を使用して描画方法を決定します。
アニメーションを使用せずに Flutter ロゴを描画する次のアプリを考えてみましょう。
import 'package:flutter/material.dart';
void main() => runApp(const LogoApp());
class LogoApp extends StatefulWidget {
const LogoApp({super.key});
@override
State<LogoApp> createState() => _LogoAppState();
}
class _LogoAppState extends State<LogoApp> {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
margin: const EdgeInsets.symmetric(vertical: 10),
height: 300,
width: 300,
child: const FlutterLogo(),
),
);
}
}
アプリのソース: アニメイト0
以下は、アニメーション化するために変更された同じコードを示しています。
ロゴをゼロからフルサイズまで成長させます。
を定義するとき、AnimationController
を渡す必要があります。vsync
物体。のvsync
パラメータについては、AnimationController
セクション。
アニメーション化されていない例からの変更点が強調表示されています。
@@ -9,16 +9,39 @@
|
|
9
9
|
State<LogoApp> createState() => _LogoAppState();
|
10
10
|
}
|
11
|
-
class _LogoAppState extends State<LogoApp> {
|
11
|
+
class _LogoAppState は State<LogoApp> を拡張しますSingleTickerProviderStateMixin を使用{
|
12
|
+
後半のアニメーション<double>アニメーション。
|
13
|
+
後期のAnimationControllerコントローラー。
|
14
|
+
|
15
|
+
@オーバーライド
|
16
|
+
void initState() {
|
17
|
+
super.initState();
|
18
|
+
コントローラー =
|
19
|
+
AnimationController(duration:constDuration(秒:2),vsync:this);
|
20
|
+
アニメーション = Tween<double>(開始: 0、終了: 300).animate(コントローラー)
|
21
|
+
..addListener(() {
|
22
|
+
setState(() {
|
23
|
+
// ここで変化した状態はアニメーションオブジェクトの値です。
|
24
|
+
});
|
25
|
+
});
|
26
|
+
コントローラー.フォワード();
|
27
|
+
}
|
28
|
+
|
12
29
|
@オーバーライド
|
13
30
|
ウィジェットのビルド(BuildContext context) {
|
14
31
|
リターンセンター(
|
15
32
|
子: コンテナ(
|
16
33
|
マージン: const EdgeInsets.metric(vertical: 10)、
|
17
|
-
身長:
|
18
|
-
幅:
|
34
|
+
身長:アニメーションの値、
|
35
|
+
幅:アニメーションの値、
|
19
36
|
子: const FlutterLogo()、
|
20
37
|
)、
|
21
38
|
);
|
22
39
|
}
|
40
|
+
|
41
|
+
@オーバーライド
|
42
|
+
void destroy() {
|
43
|
+
コントローラー.dispose();
|
44
|
+
super.dispose();
|
45
|
+
}
|
23
46
|
}
|
アプリのソース: アニメート1
のaddListener()
関数呼び出しsetState()
、
だから毎回Animation
新しい番号を生成し、
現在のフレームはダーティとしてマークされているため、build()
また呼ばれることに。のbuild()
、
コンテナの高さによってサイズが変わります。
現在使用されている幅animation.value
ハードコードされた値の代わりに。
コントローラは次の場合に廃棄してください。State
オブジェクトは
メモリリークを防ぐために破棄されます。
これらのいくつかの変更により、 Flutter で最初のアニメーションが作成されました。
AnimatedWidget による簡素化
のAnimatedWidget
基本クラスを使用すると分離できます
アニメーション コードからのコア ウィジェット コード。AnimatedWidget
を維持する必要はありませんState
アニメーションを保持するオブジェクト。以下を追加しますAnimatedLogo
クラス:
class AnimatedLogo extends AnimatedWidget {
const AnimatedLogo({super.key, required Animation<double> animation})
: super(listenable: animation);
@override
Widget build(BuildContext context) {
final animation = listenable as Animation<double>;
return Center(
child: Container(
margin: const EdgeInsets.symmetric(vertical: 10),
height: animation.value,
width: animation.value,
child: const FlutterLogo(),
),
);
}
}
AnimatedLogo
の現在値を使用します。animation
それ自体を描くとき。
のLogoApp
まだ管理していますAnimationController
そしてそのTween
、
そしてそれは通過しますAnimation
に反対するAnimatedLogo
:
@@ -1,10 +1,28 @@
|
|
1
1
|
import 'パッケージ:flutter/material.dart';
|
2
2
|
void main() => runApp(const LogoApp());
|
3
|
+
class AnimatedLogo extends AnimatedWidget {
|
4
|
+
const AnimatedLogo({super.key, 必須のアニメーション<double> アニメーション})
|
5
|
+
: スーパー(聴ける: アニメーション);
|
6
|
+
|
7
|
+
@オーバーライド
|
8
|
+
ウィジェットのビルド(BuildContext context) {
|
9
|
+
最終アニメーション =Animation<double> として聞くことができます。
|
10
|
+
リターンセンター(
|
11
|
+
子: コンテナ(
|
12
|
+
マージン: const EdgeInsets.metric(vertical: 10)、
|
13
|
+
高さ: アニメーション.値、
|
14
|
+
幅: アニメーション.値、
|
15
|
+
子: const FlutterLogo()、
|
16
|
+
)、
|
17
|
+
);
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
3
21
|
class LogoApp extends StatefulWidget {
|
4
22
|
const LogoApp({super.key});
|
5
23
|
@オーバーライド
|
6
24
|
State<LogoApp> createState() => _LogoAppState();
|
7
25
|
}
|
@@ -15,32 +33,18 @@
|
|
15
33
|
@オーバーライド
|
16
34
|
void initState() {
|
17
35
|
super.initState();
|
18
36
|
コントローラー =
|
19
37
|
AnimationController(duration:constDuration(秒:2),vsync:this);
|
20
|
-
アニメーション = Tween<double>(開始: 0、終了: 300).animate(コントローラー)
|
21
|
-
..addListener(() {
|
22
|
-
setState(() {
|
23
|
-
// ここで変化した状態はアニメーションオブジェクトの値です。
|
24
|
-
});
|
25
|
-
});
|
38
|
+
アニメーション = Tween<double>(開始: 0、終了: 300).animate(コントローラー);
|
26
39
|
コントローラー.フォワード();
|
27
40
|
}
|
28
41
|
@オーバーライド
|
29
|
-
ウィジェットのビルド(BuildContext コンテキスト)
|
30
|
-
リターンセンター(
|
31
|
-
子: コンテナ(
|
32
|
-
マージン: const EdgeInsets.metric(vertical: 10)、
|
33
|
-
高さ: アニメーション.値、
|
34
|
-
幅: アニメーション.値、
|
35
|
-
子: const FlutterLogo()、
|
36
|
-
)、
|
37
|
-
);
|
38
|
-
}
|
42
|
+
ウィジェットのビルド(BuildContext コンテキスト)=> アニメーションロゴ(アニメーション:アニメーション);
|
39
43
|
@オーバーライド
|
40
44
|
void destroy() {
|
41
45
|
コントローラー.dispose();
|
42
46
|
super.dispose();
|
43
47
|
}
|
アプリのソース: アニメート2
アニメーションの進行状況を監視する
アニメーションの状態が変化するタイミングを知ると役立つことがよくあります。
終了、前進、後進など。
この通知を受け取るには、addStatusListener()
。
次のコードは、前の例を次のように変更します。
状態の変化をリッスンし、更新を出力します。
強調表示された行は変更を示しています。
class _LogoAppState extends State<LogoApp> with SingleTickerProviderStateMixin {
late Animation<double> animation;
late AnimationController controller;
@override
void initState() {
super.initState();
controller =
AnimationController(duration: const Duration(seconds: 2), vsync: this);
animation = Tween<double>(begin: 0, end: 300).animate(controller)
..addStatusListener((status) => print('$status'));
controller.forward();
}
// ...
}
このコードを実行すると、次の出力が生成されます。
AnimationStatus.forward
AnimationStatus.completed
次に、使用しますaddStatusListener()
アニメーションを逆にするには
最初か最後に。これにより、「呼吸」エフェクトが作成されます。
@@ -35,7 +35,15 @@
|
|
35
35
|
void initState() {
|
36
36
|
super.initState();
|
37
37
|
コントローラー =
|
38
38
|
AnimationController(duration:constDuration(秒:2),vsync:this);
|
39
|
-
アニメーション = Tween<double>(開始: 0、終了: 300).animate(コントローラー)
|
39
|
+
アニメーション = Tween<double>(開始: 0、終了: 300).animate(コントローラー)
|
40
|
+
..addStatusListener((ステータス) {
|
41
|
+
if (ステータス == AnimationStatus.completed) {
|
42
|
+
コントローラー.リバース();
|
43
|
+
else if (status == AnimationStatus.dismissed) {
|
44
|
+
コントローラー.フォワード();
|
45
|
+
}
|
46
|
+
})
|
47
|
+
..addStatusListener((ステータス) => print('$status'));
|
40
48
|
コントローラー.フォワード();
|
41
49
|
}
|
アプリのソース: アニメイト3
AnimatedBuilder を使用したリファクタリング
のコードに関する 1 つの問題アニメイト3例、 アニメーションを変更するにはウィジェットを変更する必要があるということです ロゴをレンダリングします。より良い解決策 責任を異なるクラスに分けることです。
- ロゴをレンダリングする
- を定義します
Animation
物体 - トランジションをレンダリングする
この分離は、AnimatedBuilder
クラス。アンAnimatedBuilder
です
レンダーツリー内の別のクラス。好きAnimatedWidget
、AnimatedBuilder
自動的に通知を聞く
からディー6db4e-3dad-4da6-8b0a-bc6509153d31オブジェクトを作成し、ウィジェット ツリーをマークします
必要に応じて汚れるので、電話する必要はありませんaddListener()
。
のウィジェット ツリーアニメイト4例は次のようになります。
ウィジェット ツリーの一番下から、レンダリング用のコードが続きます。 ロゴは単純です:
class LogoWidget extends StatelessWidget {
const LogoWidget({super.key});
// Leave out the height and width so it fills the animating parent
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.symmetric(vertical: 10),
child: const FlutterLogo(),
);
}
}
図の中央の 3 つのブロックはすべて、build()
のメソッドGrowTransition
、 下に示された。
のGrowTransition
ウィジェット自体はステートレスであり、保持されます
遷移アニメーションを定義するために必要な最終変数のセット。
build() 関数は、AnimatedBuilder
、
これは (Anonymous
builder) メソッドとLogoWidget
オブジェクトをパラメータとして指定します。レンダリングする作業は、
遷移は実際には (Anonymous
ビルダー)
メソッドを作成します。Container
適切なサイズの
強制的にLogoWidget
ぴったりと縮むこと。
以下のコードの注意が必要な点は、子が次のように見えることです。
2回指定されているようなものです。何が起こっているのかというと、
子の外部参照が渡されます19ベッド071-17d6-4346-9b8e-b0f9552483dc、
これはそれを匿名クロージャに渡し、次にそれを使用します。
そのオブジェクトをその子として扱います。最終的な結果は、AnimatedBuilder
2 つのウィジェットの間に挿入されます
レンダーツリー内。
class GrowTransition extends StatelessWidget {
const GrowTransition(
{required this.child, required this.animation, super.key});
final Widget child;
final Animation<double> animation;
@override
Widget build(BuildContext context) {
return Center(
child: AnimatedBuilder(
animation: animation,
builder: (context, child) {
return SizedBox(
height: animation.value,
width: animation.value,
child: child,
);
},
child: child,
),
);
}
}
最後に、アニメーションを初期化するコードは非常に見栄えがします。
に似ていますアニメート2例。のinitState()
メソッドが作成するAnimationController
そしてcda0adfc-ae32-44eb-ad00-da9e1e7e0bec、
次にそれらをバインドしますanimate()
。魔法が起こるのは、
のbuild()
メソッド。GrowTransition
オブジェクトLogoWidget
子として、アニメーション オブジェクトとして
移行を推進します。この3つの要素が挙げられています
上記の箇条書きで説明します。
@@ -1,27 +1,47 @@
|
|
1
1
|
import 'パッケージ:flutter/material.dart';
|
2
2
|
void main() => runApp(const LogoApp());
|
3
|
-
クラス
|
4
|
-
定数
|
5
|
-
|
3
|
+
クラスロゴウィジェット伸びるステートレスウィジェット{
|
4
|
+
定数ロゴウィジェット({スーパーキー});
|
5
|
+
|
6
|
+
// 高さと幅を省略して、アニメーション化する親を埋めるようにします。
|
7
|
+
@オーバーライド
|
8
|
+
ウィジェットのビルド(BuildContext context) {
|
9
|
+
コンテナを返す(
|
10
|
+
マージン: const EdgeInsets.metric(vertical: 10)、
|
11
|
+
子: const FlutterLogo()、
|
12
|
+
);
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
class GrowTransition extends StatelessWidget {
|
17
|
+
const GrowTransition(
|
18
|
+
{this.child が必要、this.animation、super.key が必要});
|
19
|
+
|
20
|
+
最後のウィジェットの子。
|
21
|
+
最終アニメーション<double>アニメーション;
|
6
22
|
@オーバーライド
|
7
23
|
ウィジェットのビルド(BuildContext context) {
|
8
|
-
最終アニメーション =Animation<double> として聞くことができます。
|
9
24
|
リターンセンター(
|
10
|
-
子供:
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
25
|
+
子供:アニメーションビルダー(
|
26
|
+
アニメーション:アニメーション、
|
27
|
+
ビルダー:(コンテクスト、子供) {
|
28
|
+
戻る SizedBox(
|
29
|
+
身長:アニメーションの値、
|
30
|
+
幅: アニメーション.値、
|
31
|
+
子供:子供、
|
32
|
+
);
|
33
|
+
}、
|
34
|
+
子供:子供、
|
15
35
|
)、
|
16
36
|
);
|
17
37
|
}
|
18
38
|
}
|
19
39
|
class LogoApp extends StatefulWidget {
|
20
40
|
const LogoApp({super.key});
|
21
41
|
@オーバーライド
|
22
42
|
State<LogoApp> createState() => _LogoAppState();
|
@@ -34,18 +54,23 @@
|
|
34
54
|
@オーバーライド
|
35
55
|
void initState() {
|
36
56
|
super.initState();
|
37
57
|
コントローラー =
|
38
58
|
AnimationController(duration:constDuration(秒:2),vsync:this);
|
39
59
|
アニメーション = Tween<double>(開始: 0, 終了: 300).animate(コントローラー);
|
40
60
|
コントローラー.フォワード();
|
41
61
|
}
|
42
62
|
@オーバーライド
|
43
|
-
ウィジェットのビルド(BuildContext コンテキスト)
|
63
|
+
ウィジェットのビルド(BuildContext コンテキスト){
|
64
|
+
return GrowTransition(
|
65
|
+
アニメーション: アニメーション、
|
66
|
+
子: const LogoWidget()、
|
67
|
+
);
|
68
|
+
}
|
44
69
|
@オーバーライド
|
45
70
|
void destroy() {
|
46
71
|
コントローラー.dispose();
|
47
72
|
super.dispose();
|
48
73
|
}
|
49
74
|
}
|
アプリのソース: アニメイト4
同時アニメーション
このセクションでは、次の例に基づいて構築します。アニメーションの進行状況を監視する(アニメイト3)、使用したAnimatedWidget
継続的に出入りをアニメーション化します。場合を考えてみましょう
途中でアニメーションを付けたい場所と外側の場所を指定します。
不透明度は透明から不透明にアニメーションします。
各トゥイーンはアニメーションの側面を管理します。例えば:
controller =
AnimationController(duration: const Duration(seconds: 2), vsync: this);
sizeAnimation = Tween<double>(begin: 0, end: 300).animate(controller);
opacityAnimation = Tween<double>(begin: 0.1, end: 1).animate(controller);
サイズは次のように取得できますsizeAnimation.value
そして不透明度
とopacityAnimation.value
、しかし、のコンストラクターAnimatedWidget
1つだけかかりますAnimation
物体。この問題を解決するために、
この例では独自のものを作成しますTween
オブジェクトを作成し、明示的に計算します。
価値観。
変化AnimatedLogo
独自のものをカプセル化するTween
オブジェクト、
そしてそのbuild()
メソッド呼び出しTween.evaluate()
親のアニメーション オブジェクトで計算します
必要なサイズと不透明度の値。
次のコードは、変更を強調表示して示しています。
class AnimatedLogo extends AnimatedWidget {
const AnimatedLogo({super.key, required Animation<double> animation})
: super(listenable: animation);
// Make the Tweens static because they don't change.
static final _opacityTween = Tween<double>(begin: 0.1, end: 1);
static final _sizeTween = Tween<double>(begin: 0, end: 300);
@override
Widget build(BuildContext context) {
final animation = listenable as Animation<double>;
return Center(
child: Opacity(
opacity: _opacityTween.evaluate(animation),
child: Container(
margin: const EdgeInsets.symmetric(vertical: 10),
height: _sizeTween.evaluate(animation),
width: _sizeTween.evaluate(animation),
child: const FlutterLogo(),
),
),
);
}
}
class LogoApp extends StatefulWidget {
const LogoApp({super.key});
@override
State<LogoApp> createState() => _LogoAppState();
}
class _LogoAppState extends State<LogoApp> with SingleTickerProviderStateMixin {
late Animation<double> animation;
late AnimationController controller;
@override
void initState() {
super.initState();
controller =
AnimationController(duration: const Duration(seconds: 2), vsync: this);
animation = CurvedAnimation(parent: controller, curve: Curves.easeIn)
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.reverse();
} else if (status == AnimationStatus.dismissed) {
controller.forward();
}
});
controller.forward();
}
@override
Widget build(BuildContext context) => AnimatedLogo(animation: animation);
@override
void dispose() {
controller.dispose();
super.dispose();
}
}
アプリのソース: アニメイト5
次のステップ
このチュートリアルでは、アニメーションを作成するための基礎を提供します。
flutterを使用してTweens
, しかし、探索すべきクラスは他にもたくさんあります。
専門的なことを調べてみるとよいでしょうTween
クラス、
マテリアル デザインに固有のアニメーション、ReverseAnimation
、
共有要素のトランジション (ヒーロー アニメーションとも呼ばれます)、
物理シミュレーションとfling()
方法。
を参照してください。アニメーションのランディング ページ最新の利用可能なドキュメントと例については、こちらをご覧ください。